学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

Stanford CS193p - [7-9]

Developing Applications for iOS using SwiftUI

Total Lecture: 15

current: [7-9]

Shape,ViewModifier,Constants

Constants

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct CardView: View {
typealias Card = MemoryGame<String>.Card

let card: Card

init(_ card: Card) {
self.card = card
}

private struct Constants {
static let cornerRadius: CGFloat = 12
static let lineWidth: CGFloat = 2
static let inset: CGFloat = 5

struct FontSize {
static let largest: CGFloat = 200
static let smallest: CGFloat = 10
static let scaleFactor = smallest / largest
}
}
}

Shape

Shape是一个继承自View的协议,RoundedRectangle,Circle,Capsule

默认情况下,Shapes用当前foreground color来填充,可以通过.stroke().fill()来改变

1
func fill<S>(_ whatToFillWith: S) -> View where S: ShapeStyle

Custom Shape

1
2
3
func path(in rect: CGRect) -> Path {
return a Path
}

Animation

制作动画的一种方法是对Shape进行动画处理。另一种是通过ViewModifiers

ViewModifier

.aspectRatio(2/3)等同于.modifier(AspectModifier(2/3))
AspectModifier可以是遵从ViewModifier协议的其他东西,这里只是语法糖

Protocol

1
2
3
4
5
protocol ViewModifier {
func body(content: Content) -> some View { // Content is a "care a little bit" View
return some View that almost certainly contains content
}
}

调用方式
aView.modifier(MyViewModifier(arguments:...))

Cardify ViewModifier

ViewModifier语法糖

Text("🐶").modifier(Cardify(isFaceUp: true)) 等同于 Text("🐶").cardify(isFaceUp: true)

1
2
3
4
5
extension View {
func cardify(isFaceUp: Bool) -> some View {
return self.modifier(Cardify(isFaceUp: isFaceUp))
}
}

Protocol

协议最大用途是代码共享(code sharing),可以通过extension添加默认实现方法,协议只是事物的声明,而不是实现

filter

可作用于 Array, Range,String,Dictionary

1
filter(_ isIncluded: (Element) -> Bool) -> Array<Element>

它是Sequence协议的extension

View

1
2
3
protocol View {
var body: some View
}

默认实现

1
2
3
4
5
6
7
8
extension View {
func foregroundColor(_ color: Color) -> some View { /* implementation*/}
func font(_ font: Font?) -> some View { /* implementation*/}
func blur(radius: CGFloat, opaque: Bool) -> some View { /* implementation*/}

... and many more ...

}

Generics + Protocols (通用协议)

1
2
3
4
protocol Identifiable {
associatedtype ID
var id: ID { get }
}

类型ID是”don’t care” for Identifiable,不过必须遵从Hashable协议

1
2
3
4
protocol Identifiable {
associatedtype ID where ID: Hashable
var id: ID { get }
}

或者简写

1
2
3
4
protocol Identifiable {
associatedtype ID: Hashable
var id: ID { get }
}

some

可用于协议的不透明(opaquely)类型 传入传出于 func/var

不透明意思是,只知道它的协议类型,不知道具体类型

1
2
3
4
5
6
7
func getShape(rounded: Bool) -> some Shape {
if rounded {
return RoundredRectangle(cornerRadius: 12)
} else {
return Rectabgle()
}
}

any

let ids = [any Identifiable]()

1
2
3
func printId(of identifiable:  some Identifiable) {
print(identifiable.id)
}

Animation

Property Observers

1
2
3
4
5
6
7
8
9
var isFaceUp: bool {
willSet{
if newValue {
startUsingBonusTime()
} else {
stopUsingBounsTime()
}
}
}

属性观察不能用于@State,@Published变量,需使用.onChange(of:){}

1
2
3
4
5
6
@State private var taps = 0

Text("\(taps) taps")
.onChange(of: viewModel.cards) { newCards in
taps += 1
}

Animation

动画只是展示模型随时间发生的变化,通过ViewModifier参数反映出来,显然Shape也可以改变。

ViewModiferUI中的主要变更代理

Implicait Animation

.animation(Animation,value:)

1
2
3
Text("🐶").opacity(card.scary ? 1 :0 )
.rotationEffect(Angle.degrees(card.upsideDown ? 180 : 0))
.animation(Animation.easeInOut,value: card)

Explicitly

withAnimation(Animation) { }

Transitions

only work on Views that are inside Containers That Are Already On-Screen.

只在当前显示的容器下有效

1
2
3
4
5
6
7
8
ZStack {
if isFaceUp {
RoundredRectangle(cornerRadius: 10).stroke()
Text("🐶").transition(AnyTransition.scale)
} else {
RoundedRectabgle(cornerRadius: 10).transition(AnyTransition.identity)
}
}

Matched Geometry Effect

两个视图不在同一个容器内时

.matchedGeometryEffect(id: ID, in: Namespace) // ID type is a “don’t care”: Hashable

@Namespace private var myNamespace

.onAppear

.onAppear{}

Shape and ViewModifier Animation

所有动画发生在ShapesViewModifiersTransitionsmatchedGeometryEffect是匹配(paired)的ViewModifiers

the animation system divides the animation’s duration up into little pieces, the Shape/ViewModifier makes sure its body draws appropriately at any “piece” value

animatableData

communication with the animation system with a single var, int the Animatable protocol

如何想要动画化的ViewModifierShape都需要实现Animatable协议

1
var animatableData: Type

Typedon‘t care类型,需实现VectorArithmetic协议

AnimatblePair实现了VectorArithmetic ,包含两个VectorArithmetics

animatableDataread-write var

setting是动画系统告诉Shape/VM which “piece” to draw

getting是动画系统获取动画的开始结束点